using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Net35.Xrm.Sdk.Client
{
	internal sealed class OrganizationServiceConfiguration : IServiceConfiguration<IOrganizationService>, IWebAuthentication<IOrganizationService>, IServiceManagement<IOrganizationService>, IEndpointSwitch
	{
		private const string XrmServicesRoot = "xrmservices/";
		private ServiceConfiguration<IOrganizationService> service;
		private object _lockObject = new object();
		public event EventHandler<EndpointSwitchEventArgs> EndpointSwitched
		{
			add
			{
				this.service.EndpointSwitched += value;
			}
			remove
			{
				this.service.EndpointSwitched -= value;
			}
		}
		public event EventHandler<EndpointSwitchEventArgs> EndpointSwitchRequired
		{
			add
			{
				this.service.EndpointSwitchRequired += value;
			}
			remove
			{
				this.service.EndpointSwitchRequired -= value;
			}
		}
		public System.ServiceModel.Description.ServiceEndpoint CurrentServiceEndpoint
		{
			get
			{
				return this.service.CurrentServiceEndpoint;
			}
			set
			{
				this.service.CurrentServiceEndpoint = value;
			}
		}
		public IssuerEndpoint CurrentIssuer
		{
			get
			{
				return this.service.CurrentIssuer;
			}
			set
			{
				this.service.CurrentIssuer = value;
			}
		}
		public AuthenticationProviderType AuthenticationType
		{
			get
			{
				return this.service.AuthenticationType;
			}
		}
		public ServiceEndpointDictionary ServiceEndpoints
		{
			get
			{
				return this.service.ServiceEndpoints;
			}
		}
		public IssuerEndpointDictionary IssuerEndpoints
		{
			get
			{
				return this.service.IssuerEndpoints;
			}
		}
		public CrossRealmIssuerEndpointCollection CrossRealmIssuerEndpoints
		{
			get
			{
				return this.service.CrossRealmIssuerEndpoints;
			}
		}
		public PolicyConfiguration PolicyConfiguration
		{
			get
			{
				return this.service.PolicyConfiguration;
			}
		}
		public bool EndpointAutoSwitchEnabled
		{
			get
			{
				return this.service.EndpointAutoSwitchEnabled;
			}
			set
			{
				this.service.EndpointAutoSwitchEnabled = value;
			}
		}
		public System.Uri AlternateEndpoint
		{
			get
			{
				return this.service.AlternateEndpoint;
			}
		}
		public System.Uri PrimaryEndpoint
		{
			get
			{
				return this.service.PrimaryEndpoint;
			}
		}
		public bool IsPrimaryEndpoint
		{
			get
			{
				return this.service.IsPrimaryEndpoint;
			}
		}
		private OrganizationServiceConfiguration()
		{
		}
		internal OrganizationServiceConfiguration(System.Uri serviceUri) : this(serviceUri, false, null)
		{
		}
		internal OrganizationServiceConfiguration(System.Uri serviceUri, bool enableProxyTypes, Assembly assembly)
		{
			try
			{
				this.service = new ServiceConfiguration<IOrganizationService>(serviceUri, true);
				if (enableProxyTypes && assembly != null)
				{
					this.EnableProxyTypes(assembly);
				}
				else if (enableProxyTypes)
				{
					this.EnableProxyTypes();
				}
			}
			catch (InvalidOperationException ex2)
			{
				bool flag = true;
				System.Net.WebException ex = ex2.InnerException as System.Net.WebException;
				if (ex != null)
				{
					System.Net.HttpWebResponse httpWebResponse = ex.Response as System.Net.HttpWebResponse;
					if (httpWebResponse != null && httpWebResponse.StatusCode == System.Net.HttpStatusCode.Unauthorized)
					{
						flag = !this.AdjustServiceEndpoint(serviceUri);
					}
				}
				if (flag)
				{
					throw;
				}
			}
		}
		public void EnableProxyTypes()
		{
			ClientExceptionHelper.ThrowIfNull(this.CurrentServiceEndpoint, "CurrentServiceEndpoint");
			lock (this._lockObject)
			{
				ProxyTypesBehavior proxyTypesBehavior = this.CurrentServiceEndpoint.Behaviors.Find<ProxyTypesBehavior>();
				if (proxyTypesBehavior != null)
				{
					this.CurrentServiceEndpoint.Behaviors.Remove(proxyTypesBehavior);
				}
				this.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
			}
		}
		public void EnableProxyTypes(Assembly assembly)
		{
			ClientExceptionHelper.ThrowIfNull(assembly, "assembly");
			ClientExceptionHelper.ThrowIfNull(this.CurrentServiceEndpoint, "CurrentServiceEndpoint");
			lock (this._lockObject)
			{
				ProxyTypesBehavior proxyTypesBehavior = this.CurrentServiceEndpoint.Behaviors.Find<ProxyTypesBehavior>();
				if (proxyTypesBehavior != null)
				{
					this.CurrentServiceEndpoint.Behaviors.Remove(proxyTypesBehavior);
				}
				this.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior(assembly));
			}
		}
		public System.ServiceModel.ChannelFactory<IOrganizationService> CreateChannelFactory()
		{
			return this.service.CreateChannelFactory(ClientAuthenticationType.Kerberos);
		}
		public System.ServiceModel.ChannelFactory<IOrganizationService> CreateChannelFactory(ClientAuthenticationType clientAuthenticationType)
		{
			return this.service.CreateChannelFactory(clientAuthenticationType);
		}
		public System.ServiceModel.ChannelFactory<IOrganizationService> CreateChannelFactory(System.ServiceModel.Description.ClientCredentials clientCredentials)
		{
			return this.service.CreateChannelFactory(clientCredentials);
		}
		public SecurityTokenResponse Authenticate(System.ServiceModel.Description.ClientCredentials clientCredentials)
		{
			return this.service.Authenticate(clientCredentials);
		}
		public SecurityTokenResponse Authenticate(System.IdentityModel.Tokens.SecurityToken securityToken)
		{
			return this.service.Authenticate(securityToken);
		}
		public SecurityTokenResponse Authenticate(System.ServiceModel.Description.ClientCredentials clientCredentials, SecurityTokenResponse deviceSecurityTokenResponse)
		{
			return this.service.Authenticate(clientCredentials, deviceSecurityTokenResponse);
		}
		public SecurityTokenResponse AuthenticateDevice(System.ServiceModel.Description.ClientCredentials clientCredentials)
		{
			return this.service.AuthenticateDevice(clientCredentials);
		}
		public SecurityTokenResponse AuthenticateCrossRealm(System.ServiceModel.Description.ClientCredentials clientCredentials, string appliesTo, System.Uri crossRealmSts)
		{
			return this.service.AuthenticateCrossRealm(clientCredentials, appliesTo, crossRealmSts);
		}
		public SecurityTokenResponse AuthenticateCrossRealm(System.IdentityModel.Tokens.SecurityToken securityToken, string appliesTo, System.Uri crossRealmSts)
		{
			return this.service.AuthenticateCrossRealm(securityToken, appliesTo, crossRealmSts);
		}
		public IdentityProvider GetIdentityProvider(string userPrincipalName)
		{
			return this.service.GetIdentityProvider(userPrincipalName);
		}
		public SecurityTokenResponse Authenticate(System.ServiceModel.Description.ClientCredentials clientCredentials, System.Uri uri, string keyType)
		{
			return this.service.Authenticate(clientCredentials, uri, keyType);
		}
		public SecurityTokenResponse Authenticate(System.IdentityModel.Tokens.SecurityToken securityToken, System.Uri uri, string keyType)
		{
			return this.service.Authenticate(securityToken, uri, keyType);
		}
		private bool AdjustServiceEndpoint(System.Uri serviceUri)
		{
			System.Uri uri = OrganizationServiceConfiguration.RemoveOrgName(serviceUri);
			if (uri != null)
			{
				this.service = new ServiceConfiguration<IOrganizationService>(uri);
				if (this.service != null && this.service.ServiceEndpoints != null)
				{
					foreach (KeyValuePair<string, System.ServiceModel.Description.ServiceEndpoint> current in this.service.ServiceEndpoints)
					{
						ServiceMetadataUtility.ReplaceEndpointAddress(current.Value, serviceUri);
					}
					return true;
				}
			}
			return false;
		}
		private static System.Uri RemoveOrgName(System.Uri serviceUri)
		{
			if (!serviceUri.AbsolutePath.StartsWith("/xrmservices/", StringComparison.OrdinalIgnoreCase))
			{
				StringBuilder stringBuilder = new StringBuilder();
				for (int i = 2; i < serviceUri.Segments.Length; i++)
				{
					stringBuilder.Append(serviceUri.Segments[i]);
				}
				if (stringBuilder.Length > 0)
				{
					serviceUri = new System.UriBuilder(serviceUri.GetComponents(System.UriComponents.SchemeAndServer, System.UriFormat.UriEscaped))
					{
						Path = stringBuilder.ToString()
					}.Uri;
					return serviceUri;
				}
			}
			return null;
		}
		public AuthenticationCredentials Authenticate(AuthenticationCredentials authenticationCredentials)
		{
			return this.service.Authenticate(authenticationCredentials);
		}
		public void SwitchEndpoint()
		{
			this.service.SwitchEndpoint();
		}
		public bool HandleEndpointSwitch()
		{
			return this.service.HandleEndpointSwitch();
		}
		public bool CanSwitch(System.Uri currentUri)
		{
			return this.service.CanSwitch(currentUri);
		}
	}
}
